package com.ljh.myrpc;

import com.ljh.myrpc.config.RegistryConfig;
import com.ljh.myrpc.config.RpcConfig;
import com.ljh.myrpc.constant.RpcConstant;
import com.ljh.myrpc.registry.Registry;
import com.ljh.myrpc.registry.RegistryFactory;
import com.ljh.myrpc.utils.ConfigUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * RPC 框架应用
 * 相当于holder，存放了项目全局用到的变量。双检锁单例模式实现
 */
@Slf4j
public class RpcApplication {
    private static volatile RpcConfig rpcConfig;

    /**
     *  框架初始化，支持自定义传入配置
     * @param newRpcConfig
     */
    public static void init(RpcConfig newRpcConfig){
        rpcConfig = newRpcConfig;
        log.info("RPC框架初始化成功，配置：{}", rpcConfig);
        // 注册中心初始化
        RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
        Registry registry = RegistryFactory.getInstance(registryConfig.getRegistry());
        registry.init(registryConfig);
        log.info("注册中心初始化成功，配置：{}", registryConfig);

        // 创建并注册Shutdown Hook, jvm退出时执行操作
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("RPC框架正在关闭...");
            // 销毁注册中心
            registry.destory();
            log.info("注册中心已销毁");
        }));
    }

    /**
     * 初始化
     */
    public static void init(){
        RpcConfig newRpcConfig;
        try {
            newRpcConfig = ConfigUtils.loadConfig(RpcConfig.class, RpcConstant.DEFAULT_CONFIG_PREFIX);
        }catch (Exception e) {
            // 配置加载失败，使用默认值
            newRpcConfig = new RpcConfig();
        }
        init(newRpcConfig);
    }

    /**
     * 获取配置
     * @return
     */
    public static RpcConfig getRpcConfig(){
        if(rpcConfig == null){
            synchronized (RpcApplication.class){
                if(rpcConfig == null){
                    init();
                }
            }
        }
        return rpcConfig;
    }

}
